package cn.wen233.srpc.core.execute.server;

import cn.wen233.srpc.basic.exception.BaseException;
import cn.wen233.srpc.basic.model.Request;
import cn.wen233.srpc.basic.model.Response;
import cn.wen233.srpc.basic.model.Status;
import cn.wen233.srpc.core.execute.ServerExecutor;
import cn.wen233.srpc.core.holder.ServerServiceHolder;
import cn.wen233.srpc.core.service.spi.Order;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * ObjectStream Server 处理器
 *
 * @author wenei
 * @date 2021-10-28 16:40
 */
public class StandardServerExecutor implements ServerExecutor {

    private static final Logger LOGGER = LoggerFactory.getLogger(StandardServerExecutor.class);

    @Override
    public Response doExecute(Request request) {
        Object instance = ServerServiceHolder.getService(request.getServiceName());
        Response response = new Response();
        try {
            if (instance == null) {
                throw new BaseException("未找到serviceName={%s}的Service", request.getServiceName());
            }
            Method method = instance.getClass().getMethod(request.getMethodName(), request.getParameterTypes());
            response.setRequestId(request.getRequestId());
            response.status(Status.SUCCESS);
            Object result = method.invoke(instance, request.getParameters());
            response.setData(result);
        } catch (NoSuchMethodException e) {
            LOGGER.warn("没有找到指定 {} 的 {} 方法", request.getServiceName(), request.getMethodName());
            response.status(Status.FAILURE);
        } catch (IllegalArgumentException | InvocationTargetException | IllegalAccessException e ) {
            LOGGER.warn("反射调用方法时出错", e);
            response.status(Status.FAILURE);
        } catch (BaseException e) {
            LOGGER.warn("BaseException: " + e.getMessage());
            response.status(Status.FAILURE);
            response.setMessage(e.getMessage());
        }
        return response;
    }
}
